package gases.as3.librarys.core.net.socket
{
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.events.SecurityErrorEvent;
	import flash.net.Socket;
	import flash.system.Security;
	
	public class BaseSocket extends EventDispatcher
	{
		/**
		 * 基本SOCKT 
		 * @param host IP地址
		 * @param port 端口
		 * @param securityPort 安全协议端口
		 * 
		 */			
		public function BaseSocket(host:String = null,port:int = 0,securityPort:int = 0)
		{
			_host = host;
			_port = port;
			_securityPort = securityPort;
			initialize();
		}
		
		protected function initialize():void
		{
			_buffers = new Array();
			
			_socket = new Socket();
			_socket.addEventListener(Event.CONNECT,connectHandler);
			_socket.addEventListener(Event.CLOSE,closeHandler);
			_socket.addEventListener(IOErrorEvent.IO_ERROR,ioErrorHandler);
			_socket.addEventListener(ProgressEvent.SOCKET_DATA,socketDataHandler);
			//若对 Socket.connect() 的调用尝试连接到调用方安全沙箱外部的服务器或端口号低于 1024 的端口，则进行调度。
			_socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR,securityErrorHandler);
		}
		
		/**
		 * 写入需要发送的值 
		 * @param obj 写入的对象
		 * @param isSend 是否立即发送
		 * 
		 */		
		public function writeInSocket(obj:Object,isSend:Boolean = true):void
		{
			throw new Error("需要被重写");
		}
		
		
		/**
		 * 
		 * 对socket所有字节进行刷新
		 */		
		public final function send():void
		{
			_socket.flush();
		}
		
		/**
		 * 
		 * 用来显示socket是否已经连接上了
		 * 
		 */		
		public final function get connected():Boolean
		{
			return _socket.connected;
		}
		
		/**
		 * 如果socket没有连接 ，socket连接主机
		 * 
		 */		
		public final function connect():void
		{
			if(!_socket.connected)
			{
				if(_securityPort != 0)
				{
					var url:String = "xmlsocket://" + _host + ":" + _securityPort;
					Security.loadPolicyFile(url);
				}
				_socket.connect(host,port);
			}
		}
		
		/**
		 * 关闭socket连接
		 * 
		 */		
		public final function close():void
		{
			if(_socket.connected)
				_socket.close();
		}
		
		public final function get securityPort():int
		{
			return _securityPort;
		}
		
		public final function set securityPort(value:int):void
		{
			_securityPort = value;
		}
		
		public final function get port():int
		{
			return _port;
		}
		
		public final function set port(value:int):void
		{
			_port = value;
		}
		
		public final function get host():String
		{
			return _host;
		}
		
		public final function set host(value:String):void
		{
			_host = value;
		}
		
		/**
		 * 处理添加的socket事件 
		 * 
		 */		
		public function dispose():void
		{
			clearBuffer();
			_buffers = null;
			if(_socket)
			{
				if(_socket.connected)
					_socket.close();
				_socket.removeEventListener(Event.CONNECT,connectHandler);
				_socket.removeEventListener(Event.CLOSE,closeHandler);
				_socket.removeEventListener(IOErrorEvent.IO_ERROR,ioErrorHandler);
				_socket.removeEventListener(ProgressEvent.SOCKET_DATA,socketDataHandler);
				_socket.removeEventListener(SecurityErrorEvent.SECURITY_ERROR,securityErrorHandler);
			}
			_socket = null;
		}
		
		/**
		 * 清空数据发送缓存池 
		 * 
		 */		
		public function clearBuffer():void
		{
			while(_buffers.length > 0)
				_buffers.pop();
		}
		
		protected function sendBuffer():void
		{
			if(_buffers.length > 0)
			{
				while(_buffers.length > 0)
				{
					var bu:Object = _buffers.shift();
					writeInSocket(bu,false);
				}
				send();
			}
		}
		
		/**
		 * 解析数据 
		 * 在子类里重写该方法，这个方法用来解析socket数据
		 */		
		protected function resolveSocketData():void
		{
			throw new Error("需要被override");
		}
		
		protected function connectHandler(event:Event):void
		{
			trace("socket connect");
			sendBuffer();
		}
		
		protected function closeHandler(event:Event):void
		{
			trace(event.type);
		}
		
		protected function ioErrorHandler(event:IOErrorEvent):void
		{
			trace(event.text);
		}
		
		/**
		 * 
		 * @param event
		 * 如果连接成功之后解析数据
		 * 
		 */		
		private function socketDataHandler(event:ProgressEvent):void
		{
			if(!connected)
				return;
			resolveSocketData();
		}
		
		protected function securityErrorHandler(event:SecurityErrorEvent):void
		{
			trace(event.text);
		}
		
		/**
		 * 指定主机端口，主机名字，安全协议端口，_socket,传输对象数组
		 */		
		private var _port:int;
		private var _host:String;
		private var _securityPort:int;
		protected var _socket:Socket;
		protected var _buffers:Array;//存储要发送的对象
	}
}